﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FourWayClimbingDemo.Chess
{
    /// <summary>
    /// 棋盘
    /// </summary>
    public class ChessBoard
    {
        private int[] _positions = new int[16];  //棋盘所有坐标位置
        private List<ChessPiece> _player1ChessPieces = null;  //选手1的棋子
        private List<ChessPiece> _player2ChessPieces = null;  //选手2的棋子

        public ChessBoard() { 
        
        }

        /// <summary>
        /// 初始化棋盘
        /// </summary>
        public void Init(List<ChessPiece> player1ChessPieces, List<ChessPiece> player2ChessPieces) 
        {
            this._player1ChessPieces = player1ChessPieces;
            this._player2ChessPieces = player2ChessPieces;
        }

        /// <summary>
        /// 将选手的棋子摆到棋盘中
        /// </summary>
        private void SetBoard() 
        {
            for (int i=0;i<_positions.Length;i++) {
                _positions[i] = 0;
            }

            _player1ChessPieces.ForEach(item=> {
                if (!item.IsDead) {
                    var pos = item.GetPosition();
                    _positions[PositionsIndex(pos.row, pos.col)] = 1;
                }
            });

            _player2ChessPieces.ForEach(item=> {
                if (!item.IsDead)
                {
                    var pos = item.GetPosition();
                    _positions[PositionsIndex(pos.row, pos.col)] = -1;
                }
            });
        }

        /// <summary>
        /// 棋盘坐标和真是数据位置的转换
        /// </summary>
        private int PositionsIndex(int row,int col) {
            return (row * 4) + col;
        }

        /// <summary>
        /// 获取棋盘棋子的标记，没有棋子就是默认棋盘标记
        /// </summary>
        private string GetChessPieceTag(int row, int col)
        {
            int chessPieces = _positions[PositionsIndex(row,col)];
            string res = string.Empty;
            switch (chessPieces)
            {
                case 0:
                    res = "+";
                    break;
                case 1:
                    res = _player1ChessPieces[0].Tag;
                    break;
                case -1:
                    res = _player2ChessPieces[0].Tag;
                    break;
            }
            return res;
        }

        /// <summary>
        /// 获取棋盘数据
        /// </summary>
        public int[] GetBoard() {
            SetBoard();
            return _positions;
        }

        /// <summary>
        /// 渲染棋盘
        /// </summary>
        public string Render() {
            SetBoard();
            StringBuilder sb = new StringBuilder();
            sb.Append("       1    2    3    4    \n");
            sb.Append($"     1 { GetChessPieceTag(0, 0)}----{GetChessPieceTag(0, 1)}----{GetChessPieceTag(0, 2)}----{GetChessPieceTag(0, 3)} 1");
            sb.Append("\n");
            sb.Append("       |    |    |    |  ");
            sb.Append("\n");
            sb.Append($"     2 { GetChessPieceTag(1, 0)}----{GetChessPieceTag(1, 1)}----{GetChessPieceTag(1, 2)}----{GetChessPieceTag(1, 3)} 2");
            sb.Append("\n");
            sb.Append("       |    |    |    |  ");
            sb.Append("\n");
            sb.Append($"     3 { GetChessPieceTag(2, 0)}----{GetChessPieceTag(2, 1)}----{GetChessPieceTag(2, 2)}----{GetChessPieceTag(2, 3)} 3");
            sb.Append("\n");
            sb.Append("       |    |    |    |  ");
            sb.Append("\n");
            sb.Append($"     4 { GetChessPieceTag(3, 0)}----{GetChessPieceTag(3, 1)}----{GetChessPieceTag(3, 2)}----{GetChessPieceTag(3, 3)} 4");
            sb.Append("\n");
            sb.Append("       1    2    3    4    \n");            
            return sb.ToString();
        }

        /// <summary>
        /// 判断棋位是否合法
        /// </summary>
        public Boolean CheckPositionVaild(int row,int col) {
            return (0 <= row && row <= 3) && (0 <= col && col <= 3);
        }

        public Boolean CheckPositionVaild((int row, int col) pos)
        {
            return (0 <= pos.row && pos.row <= 3) && (0 <= pos.col && pos.col <= 3);
        }

        /// <summary>
        /// 判断棋位是否是空的 没有棋子
        /// </summary>
        public Boolean IsEmpty(int row,int col) {
            return _positions[PositionsIndex(row, col)] == 0;
        }

        /// <summary>
        /// 判断棋位是否是空的 没有棋子
        /// </summary>
        public Boolean IsEmpty((int row, int col) pos)
        {
            return _positions[PositionsIndex(pos.row, pos.col)] == 0;
        }

        /// <summary>
        /// 从棋盘移除棋子
        /// </summary>
        public void RemoveChessPiece(int row,int col) {
            var cp = _player1ChessPieces.FirstOrDefault(x => x.IsMine(row, col));
            if (cp == null) cp = _player2ChessPieces.FirstOrDefault(x => x.IsMine(row, col));
            if (cp != null) cp.Dead();
        }

        /// <summary>
        /// 获取棋子周围的棋位
        /// </summary>
        public (int row, int col)? GetChessPieceAround(int row,int col,Dir dir) {
            if (!CheckPositionVaild(row, col)) return null;
            switch (dir)
            {
                case Dir.LEFT:
                    col--;
                    break;
                case Dir.RIGHT:
                    col++;
                    break;
                case Dir.TOP:
                    row--;
                    break;
                case Dir.BOTTOM:
                    row++;
                    break;
            }
            if (!CheckPositionVaild(row, col)) return null;
            return (row,col);
        }

        public (int row, int col)? GetChessPieceAround(ChessPiece chessPiece, Dir dir)
        {
            var pos = chessPiece.GetPosition();
            return GetChessPieceAround(pos.row,pos.col,dir);
        }

        public (int row, int col)? GetChessPieceAround((int row, int col) pos, Dir dir)
        {      
            return GetChessPieceAround(pos.row, pos.col, dir);
        }

    }
}
